package Thread;

/*多线程并发访问同一资源时，就会形成"抢"的
现象.由于线程切换时机不确定,可能导致执行
代码顺序的混乱，严重时会导致系统瘫痪。*/

public class SynchronizedDemo1 {
    public static void main(String[] args) {
        Table table=new Table();
        Thread thread=new Thread(){
          public void run(){
              while (true){
                  int bean=table.getBeans();
                  Thread.yield();
                  System.out.println(getName()+":"+bean);
              }
          }
        };
        thread.start();

        Thread thread1=new Thread(){
            public void run(){
                while (true){
                    int bean=table.getBeans();
                    Thread.yield();
                    System.out.println(getName()+":"+bean);
                }
            }
        };
        thread1.start();
    }
}


class Table{
    //假如桌子上有20个豆子
    private int beans=20;

//    当一个方法被synchronized修饰后，该方法
//    为同步方法,即:多个线程不能同时进入方法
//    内部执行，
//    对于成员方法而言, synchronized会在一个
//    线程调用该方法是将该方法所属对象加锁
//    其他线程在执行该方法时由于执行方法的
//    线程没有释放锁,所以只能在方法外阻塞，
//    直到持有方法锁的线程将方法执行完毕。
//    所以,解决多线程并发执行安全问题的办法
//    就是将"抢"变为"排队"

    public synchronized int getBeans(){
        if (beans==0){
            throw new RuntimeException("没有豆子了");
        }
        Thread.yield();
        return beans--;
    }
}
